﻿using System;

namespace AIC_Notification
{
    class Program
    {
        static void InternalTestParam()
        {
            // Inline Settings
            Statistics.ApplicationType = ApplicationType.sof;
            Statistics.RunType = RunType.full;
            Global.ProcessTaskList = false;
            Global.SendReportAsEmail = false;
            Global.WaitUntilStart = 0;
            Global.LogDisplayLevel = 0;

            Global.Reports.Clear();

            Global.Reports.Add(new EssayPendingReportForAC(false));
            Global.Reports.Add(new EssayPendingReportForAM(false));
            Global.Reports.Add(new StudentStatusReportForAC(StudentStatusReportForAC.DisplayTable.partial));
            Global.Reports.Add(new StudentStatusReportForAM(StudentStatusReportForAC.DisplayTable.partial));
            Global.Reports.Add(new StudentStatusReportForLT());
            //Global.Reports.Add(new StudentStatusReportForStudent());
            //Global.Reports.Add(new TeacherStatusForLT());
            Global.Reports.Add(new SchoolListForAC());
            Global.Reports.Add(new SchoolListForAM());
            //Global.Reports.Add(new GuidanceStudentStatusForAC());
            //Global.Reports.Add(new GuidanceStudentStatusForAM());
            Global.Reports.Add(new BoardIssueReport());
        }

        static void Process()
        {
            try
            {
                Global.SetProgram();
                Global.SetOutputDirectory();
                Global.SysUtil.Initialize();
                RallyHelper.Initialize();

                // Initizlise Data Sources
                if (!Global.InitializeDataSource())
                    return;
                if (!SchoolDB.Initialize())
                    return;
                if (!TeacherDB.Initialize())
                    return;
                if (!CityDB.Initialize())
                    return;

                // Wait 15 sec before running
                Global.SysUtil.ConfirmBeforeBegin(Global.WaitUntilStart);

                Global.SysUtil.Log(String.Format("Start Time: {0}", Statistics.StartTime));

                // Read in board information from Trello or from Json
                TrelloProcessorAIC Processor = null;
                if (Statistics.ApplicationType == ApplicationType.sof)
                {
                    Processor = new TrelloProcessorSOF();
                    Processor.Initialize(Global.config.TrelloAppKey, Global.config.SOF_TrelloUserToken);
                }
                else if (Statistics.ApplicationType == ApplicationType.guidance)
                {
                    Processor = new TrelloProcessorGuidance();
                    Processor.Initialize(Global.config.TrelloAppKey, Global.config.Guidance_TrelloUserToken);
                }
                else
                {
                    Global.SysUtil.Log(String.Format("Unsupported Application Type"), 2);
                }

                Processor.Process();

                // Save configuration
                Global.config.Save();

                // Calculate Application, School, Essay/Tasks Data
                if (Statistics.ApplicationType == ApplicationType.sof)
                {
                    StatisticsHelper StatisticsHelper = new StatisticsHelper();
                    StatisticsHelper.CalculteStatistics();
                    StatisticsHelper.CalculateAllEssayStatistics();
                }
                else if (Statistics.ApplicationType == ApplicationType.guidance)
                {
                }
                else
                {
                    Global.SysUtil.Log(String.Format("Unsupported Application Type"), 2);
                }

                // Generate Reports
                Global.SysUtil.InitializeEmail(Global.config.Office365UserName, Global.config.Office365UserPassword);

                if (Global.Reports.Count > 0)
                {
                    Global.SysUtil.Log(String.Format("Report Generation Start"), 1);
                    foreach (var Report in Global.Reports)
                    {
                        Global.SysUtil.Log(String.Format("Generating: {0}", Report.ReportTitle), 1);
                        Report.SendReportAsEmail();
                    }
                    Global.SysUtil.Log(String.Format("Report Generation End"), 1);
                }
                else
                    Global.SysUtil.Log(String.Format("No Report"), 1);
            }
#if (!DEBUG)
            catch (Exception ex)
            {
                Global.SysUtil.Log(ex.ToString(), 2);
            }
#endif
            finally
            {
                // Final logs
                if (Statistics.TotalBoard != 0 && Statistics.ProcessingBoard == Statistics.TotalBoard) // Success
                {
                    TimeSpan TimeLapped = Statistics.EndTime - Statistics.StartTime;

                    Global.SysUtil.Log(String.Format("End Time: {0}", Statistics.EndTime));
                    Global.SysUtil.Log(String.Format("Total Run Time: {0}", TimeLapped));
                    Global.SysUtil.Log(String.Format("Total Run Time: {0:0.00}", TimeLapped.TotalSeconds / Statistics.TotalBoard));
                    Global.SysUtil.Log(String.Format("Time Per Board: {0:0.00}", TimeLapped.TotalSeconds / Statistics.TotalBoard));
                }
                else // Failure
                {
                    // Attachments.Add(Global.LogPathFile); // Disable Log file until we have a zip
                }
                Global.SysUtil.Log(String.Format("Total Number of Boards: {0}", Statistics.TotalBoard));
                Global.SysUtil.Log(String.Format("Board Processed: {0}", Statistics.ProcessingBoard));

                // Close log streams
                Global.SysUtil.FlushClose();

                // Send Run Status Report
                Console.WriteLine(String.Format("Sending Run Status Report"), 1);
                RunStatusReport RunStatusReport = new RunStatusReport();
                RunStatusReport.SendReportAsEmail();
            }
        }

        static void Main(string[] args)
        {
            Statistics.Initialize();
            // Initialize global variables
            Global.Initialize();
            Global.SysUtil = new Utility();

            // Deserialize configuration directly from a JSON file
            if (!Global.config.Load())
                return;

            Global.SysUtil.ParseCommandLine(args);

            if (args.Length == 0)
            {
                InternalTestParam();
                Process();
            }
            else
            {
                if ((args.Length == 2) && (Statistics.ApplicationType != ApplicationType.unsupported))
                {
                    Scheduler Scheduler = null;

                    if (Statistics.ApplicationType == ApplicationType.sof)
                        Scheduler = new SOF_Scheduler();
                    else if (Statistics.ApplicationType == ApplicationType.guidance)
                        Scheduler = new Guidance_Scheduler();

                    if (Scheduler != null)
                    {
                        Global.SendReportAsEmail = true;

                        Scheduler.Initizlize();
                        Scheduler.Set();
                        Process();
                    }
                }
                else
                {
                    Process();
                }
            }
        }
    }
}
